package com.ruoyi.huanjing.controller;

import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.io.File;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.redis.RedisCache;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;

import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.huanjing.mapper.FileInfoMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.huanjing.domain.FileInfo;
import com.ruoyi.huanjing.service.IFileInfoService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

/**
 * 文件信息Controller
 *
 * @author ruoyi
 * @date 2025-07-12
 */
@RestController
@RequestMapping("/xx/file_info")
public class FileInfoController extends BaseController {
    @Autowired
    private IFileInfoService fileInfoService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private FileInfoMapper fileInfoMapper;
    @Autowired
    private RedisCache redisCache;


    /**
     * 查询文件信息列表
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:list')")
    @GetMapping("/list")
    public TableDataInfo list(FileInfo fileInfo) {
        startPage();
        List<FileInfo> list = fileInfoService.selectFileInfoList(fileInfo);
        return getDataTable(list);
    }

    /**
     * 导出文件信息列表
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:export')")
    @Log(title = "文件信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FileInfo fileInfo) {
        List<FileInfo> list = fileInfoService.selectFileInfoList(fileInfo);
        ExcelUtil<FileInfo> util = new ExcelUtil<FileInfo>(FileInfo.class);
        util.exportExcel(response, list, "文件信息数据");
    }

    /**
     * 获取文件信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(fileInfoService.selectFileInfoById(id));
    }

    /**
     * 新增文件信息
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:add')")
    @Log(title = "文件信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FileInfo fileInfo) {
        return toAjax(fileInfoService.insertFileInfo(fileInfo));
    }

    /**
     * 修改文件信息
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:edit')")
    @Log(title = "文件信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FileInfo fileInfo) {
        return toAjax(fileInfoService.updateFileInfo(fileInfo));
    }

    /**
     * 删除文件信息
     */
    @PreAuthorize("@ss.hasPermi('xx:file_info:remove')")
    @Log(title = "文件信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(fileInfoService.deleteFileInfoByIds(ids));
    }

    /**
     * 遍历文件
     */
    @Anonymous
    @GetMapping("/bianli")
    public AjaxResult bianli() {
        String disk = redisCache.getCacheObject("disk").toString();
        String rootDir =disk+ "环境数据";
        AjaxResult bianli = fileInfoService.bianli(rootDir);
        return bianli;
    }

    /**
     * 扫描磁盘，获取盘符
     * @return
     */
    @Anonymous
    @GetMapping("/diskscanner")
    public List<String> diskscanner() {
        // 获取所有磁盘根目录
        return fileInfoService.diskScanner();
    }

    /**
     * 存储盘符进缓存
     */
    @Anonymous
    @PostMapping("/saveDisk")
    public AjaxResult saveDisk(@RequestBody Map<String, String> map) {
        String disk = map.get("disk");
        return toAjax(fileInfoService.saveDisk(disk));
    }

    /**
     * 获取tiff
     */
    @Anonymous
    @PostMapping("/getTiff")
    public List<String> getTiff(@RequestBody Map<String, String> map) {
        return fileInfoService.getTiffDisk(map);
    }

    /**
     * 初始化扫描硬盘,获取盘符
     */
    @Anonymous
    @PostConstruct
    public void init() {
        String disk="";
        fileInfoService.saveDisk(disk);
    }

    private static List<String> tilsList=new ArrayList<>(Arrays.asList("台湾", "香港"));

    /*时间轴*/
    @Anonymous
    @GetMapping("/listByFolder")
    public AjaxResult listFilesByFolder(@RequestParam String folderPath,
                                        @RequestParam(required = false) String productName,
                                        @RequestParam(required = false) String fileName,
                                        @RequestParam(required = false) Date startTime,
                                        @RequestParam(required = false) Date endTime,
                                        @RequestParam(defaultValue = "1") Integer pageNum,
                                        @RequestParam(defaultValue = "10") Integer pageSize) {
        if (StringUtils.isEmpty(folderPath)) {
            return AjaxResult.error("文件夹路径不能为空");
        }

        //动态获取盘符
        String disk = redisCache.getCacheObject("disk").toString();

        try {
            boolean haveChar=false;
            String fileNameTils="";
            for (String s : tilsList) {
                if (folderPath.contains(s)) {
                    haveChar = true;
                    fileNameTils=s;
                    break;
                }
            }
            if (!haveChar){
                // 1. 将所有分隔符统一为双反斜杠 `\\`
                folderPath = folderPath.replace("/", "\\\\"); // 替换 `/` 为 `\\`
                folderPath = folderPath.replace("\\", "\\\\"); // 替换 `\` 为 `\\`

                // 2. 确保路径末尾有双反斜杠 `\\`
                if (!folderPath.endsWith("\\\\")) {
                    folderPath = folderPath + "\\\\";
                }
                folderPath=folderPath.substring(2);
            }else {
                folderPath="/images/地面倾斜摄影/"+fileNameTils;
            }


            // 3. 创建分页对象
            Page<FileInfo> page = new Page<>(pageNum, pageSize);

            // 4. 创建查询条件
            QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();

            queryWrapper.likeRight("file_path", folderPath);
            String diskIdentity = redisCache.getCacheObject("diskIdentity").toString();
            if (StringUtils.isNotEmpty(diskIdentity)) {
                queryWrapper.eq("disk_identity", diskIdentity);
            } else {
                // 可选：如果没有硬盘标识，特殊处理（如返回空）
                queryWrapper.eq("1", "0"); // 构造假条件，避免全表查询
            }
            if (StringUtils.isNotEmpty(productName)) {
                queryWrapper.like("product_name", productName);
            }
            if (StringUtils.isNotEmpty(fileName)) {
                queryWrapper.like("file_name", fileName);
            }
            if (startTime != null) {
                queryWrapper.ge("time", startTime);
            }
            if (endTime != null) {
                queryWrapper.le("time", endTime);
            }

            // 5. 执行分页查询
            Page<FileInfo> fileInfoPage = fileInfoMapper.selectPage(page, queryWrapper);
            if (!haveChar){
                //根据盘符替代路径
                fileInfoPage.getRecords().forEach(fileInfo -> {
                    fileInfo.setFilePath(disk+fileInfo.getFilePath());
                });
            }

            Map<String, Object> result = new HashMap<>();
            result.put("list", fileInfoPage.getRecords());
            result.put("total", fileInfoPage.getTotal());
            result.put("pageNum", fileInfoPage.getCurrent());
            result.put("pageSize", fileInfoPage.getSize());

            return AjaxResult.success("查询成功", result);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查询失败：" + e.getMessage());
        }
    }

    /*返回年月日列表*/
    @Anonymous
    @GetMapping("/dayList")
    public AjaxResult dayList(@RequestParam String folderPath, String year, String month) {
        if (StringUtils.isEmpty(folderPath)) {
            return AjaxResult.error("文件夹路径不能为空");
        }

        try {
            // 1. 将所有分隔符统一为双反斜杠 `\\`
            folderPath = folderPath.replace("/", "\\\\"); // 替换 `/` 为 `\\`
            folderPath = folderPath.replace("\\", "\\\\"); // 替换 `\` 为 `\\`

            // 2. 确保路径末尾有双反斜杠 `\\`
            if (!folderPath.endsWith("\\\\")) {
                folderPath = folderPath + "\\\\";
            }

            //匹配时不带盘符
            folderPath=folderPath.substring(2);

            // 3. 执行查询
            QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<FileInfo>().likeRight("file_path", folderPath)
                    .eq("disk_identity", redisCache.getCacheObject("diskIdentity").toString());
            List<FileInfo> fileInfos = fileInfoMapper.selectList(queryWrapper);
            Set<String> uniqueDates = new LinkedHashSet<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (FileInfo fileInfo : fileInfos) {
                Date date = fileInfo.getTime();
                if (date != null) {
                    String dateStr = sdf.format(date);
                    uniqueDates.add(dateStr);
                }
            }
            
            // 添加日期排序逻辑
            List<String> sortedDates = new ArrayList<>(uniqueDates);
            Collections.sort(sortedDates);
            
            // 初始化三个数组，默认为空
            List<String> years = new ArrayList<>();
            List<String> months = new ArrayList<>();
            List<String> days = new ArrayList<>();
            
            // 根据传入参数筛选数据
            if (StringUtils.isEmpty(year) && StringUtils.isEmpty(month)) {
                // 首次调用，返回年份列表
                Set<String> yearsSet = new LinkedHashSet<>();
                for (String dateStr : sortedDates) {
                    yearsSet.add(dateStr.split("-")[0]);
                }
                years = new ArrayList<>(yearsSet);
                Collections.sort(years);
            } else if (StringUtils.isNotBlank(year) && StringUtils.isEmpty(month)) {
                // 传入年份，返回月份列表
                years.add(year);
                Set<String> monthsSet = new LinkedHashSet<>();
                for (String dateStr : sortedDates) {
                    String[] parts = dateStr.split("-");
                    if (parts[0].equals(year)) {
                        monthsSet.add(parts[1]);
                    }
                }
                months = new ArrayList<>(monthsSet);
                Collections.sort(months);
            } else if (StringUtils.isNotBlank(year) && StringUtils.isNotBlank(month)) {
                // 传入年份和月份，返回日期列表
                years.add(year);
                months.add(month);
                Set<String> daysSet = new LinkedHashSet<>();
                for (String dateStr : sortedDates) {
                    String[] parts = dateStr.split("-");
                    if (parts[0].equals(year) && parts[1].equals(month)) {
                        daysSet.add(parts[2]);
                    }
                }
                days = new ArrayList<>(daysSet);
                Collections.sort(days);
            }
            
            // 构建包含三个数组的结果对象，确保始终返回这三个键
            Map<String, List<String>> result = new HashMap<>();
            result.put("years", years);
            result.put("months", months);
            result.put("days", days);

            return AjaxResult.success("查询成功", result);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查询失败：" + e.getMessage());
        }
    }

    /*根据时间查询文件列表*/
    @Anonymous
    @GetMapping("/filePathList")
    public AjaxResult filePathList(@RequestParam String time, String folderPath) {
        if (StringUtils.isEmpty(time)) {
            return AjaxResult.error("文件夹路径不能为空");
        }

        //动态获取盘符
        String disk = redisCache.getCacheObject("disk").toString();

        try {
            // 1. 将所有分隔符统一为双反斜杠 `\\`
            folderPath = folderPath.replace("/", "\\\\"); // 替换 `/` 为 `\\`
            folderPath = folderPath.replace("\\", "\\\\"); // 替换 `\` 为 `\\`

            // 2. 确保路径末尾有双反斜杠 `\\`
            if (!folderPath.endsWith("\\\\")) {
                folderPath = folderPath + "\\\\";
            }

            //匹配时不带盘符
            folderPath=folderPath.substring(2);

            // 3. 执行查询
            List<FileInfo> fileInfos = fileInfoMapper.selectList(new QueryWrapper<FileInfo>().likeRight("file_path", folderPath)
                    .eq("disk_identity", redisCache.getCacheObject("diskIdentity").toString())
                    // 将 likeLeft 改为 between 以精确匹配日期范围
                    .between("time", time + " 00:00:00", time + " 23:59:59"));

            // 格式化time字段为只保留时分秒
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            List<Map<String, Object>> resultList = new ArrayList<>();
            
            for (FileInfo fileInfo : fileInfos) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", fileInfo.getId());
                map.put("productName", fileInfo.getProductName());
                map.put("fileName", fileInfo.getFileName());
                map.put("size", fileInfo.getSize());
                map.put("fileType", fileInfo.getFileType());
                //匹配完后，动态拼接盘符
                map.put("filePath", disk+fileInfo.getFilePath());

                
                Date date = fileInfo.getTime();
                if (date != null) {
                    map.put("time", sdf.format(date));
                } else {
                    map.put("time", "");
                }
                
                resultList.add(map);
            }
            return AjaxResult.success("查询成功", resultList);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查询失败：" + e.getMessage());
        }
    }

    @Anonymous
    @GetMapping("/tanhao")
    public AjaxResult tanhao(@RequestParam String folderPath) {
        if (StringUtils.isEmpty(folderPath)) {
            return AjaxResult.error("文件夹路径不能为空");
        }

        // 1. 将所有分隔符统一为双反斜杠 `\\`
        folderPath = folderPath.replace("/", "\\\\"); // 替换 `/` 为 `\\`
        folderPath = folderPath.replace("\\", "\\\\"); // 替换 `\` 为 `\\`

        // 2. 确保路径末尾有双反斜杠 `\\`
        if (!folderPath.endsWith("\\\\")) {
            folderPath = folderPath + "\\\\";
        }

        List<FileInfo> list = fileInfoMapper.selectFilesByFolderPath(folderPath);

        // 按 productName 分组
        Map<String, List<FileInfo>> typeMap = new HashMap<>();
        for (FileInfo fileInfo : list) {
            typeMap.computeIfAbsent("1", k -> new ArrayList<>()).add(fileInfo);
        }

//        List<Map<String,Map<String, Object>>> resultList = new ArrayList<>();
//        Map<String,Map<String, Object>> map = new HashMap<>();
        Map<String, Object> res = new HashMap<>();
        for (String productName : typeMap.keySet()) {
//            Map<String, Object> res = new HashMap<>();
            List<FileInfo> fileInfos = typeMap.get(productName);
            res.put("条目数", fileInfos.size());

            double totalSizeInMB = 0;
            for (FileInfo fileInfo : fileInfos) {
                String sizeStr = fileInfo.getSize().trim();
                if (sizeStr.contains("MB")) {
                    totalSizeInMB += Double.parseDouble(sizeStr.replace("MB", "").trim());
                } else if (sizeStr.contains("GB")) {
                    totalSizeInMB += Double.parseDouble(sizeStr.replace("GB", "").trim()) * 1024;
                }
            }
            // 将 MB 转换为字节数并调用 formatFileSize 方法
            long totalBytes = (long) (totalSizeInMB * 1024 * 1024);
            res.put("数据大小", formatFileSize(totalBytes));
//            res.put("数据总量", 12345678);
            res.put("数据格式", fileInfos.get(0).getFileType());
            res.put("产品", StringUtils.isNotEmpty(fileInfos.get(0).getProductName()) ?fileInfos.get(0).getProductName():"MYD2013541841");

//            map.put(productName,res);
//            resultList.add(map);
        }

        return AjaxResult.success(res);
    }

    private String formatFileSize(long bytes) {
        if (bytes < 1024) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        String pre = "KMGTPE".charAt(exp - 1) + "B";
        return String.format("%.2f %s", bytes / Math.pow(1024, exp), pre);
    }

    @Anonymous
    @GetMapping("/downloadFile")
    public ResponseEntity<Resource> downloadFile(@RequestParam String filePath) {
        // 替换路径中的反斜杠为正斜杠，解决URL中无效字符问题
        String normalizedFilePath = filePath.replace('\\', '/');
        File file = new File(normalizedFilePath);

        if (!file.exists() || !file.isFile()) {
            return ResponseEntity.notFound().build();
        }

        try {
            Resource resource = new UrlResource(file.toURI());
            if (resource.exists()) {
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .contentLength(file.length())
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}